<?php

use Upfor\UpforPHP\Model;
use Upfor\UpforPHP\Exception\PageNotFound;
use SinoPHP\BbdBoss\Library\Queue;

/**
 * Get a single model instance
 *
 * Usage:
 *      model('User')
 *      model('UserLog')
 *      model('Domain/ActionLog')
 *
 * @param  string $modelName
 * @param  mixed  $params
 * @return Model
 * @throws ErrorException
 */
function model($modelName, $params = null) {
    static $classMap = array();

    $modelName = str_replace('/', '\\', $modelName);
    $key = md5($modelName . serialize($params));

    if (!isset($classMap[$key])) {
        $className = '\\SinoPHP\\BbdBoss\\Model\\' . $modelName;
        if (!class_exists($className)) {
            $className = '\\Upfor\\UpforPHP\\Model';
        }

        $classMap[$key] = new $className($params);
        if (!$classMap[$key]->getTableName()) {
            $className = trim($modelName, '\\');
            $className = str_replace('\\', '', $className);
            $tableName = preg_replace("/(?!^)(?=[A-Z])/", "_\$2", $className);
            $classMap[$key]->setTableName(strtolower($tableName));
        }
    }

    return $classMap[$key];
}

/**
 * 获取管理员登录TOKEN
 *
 * @return string
 */
function getAdminUserLoginToken() {
    $token = config('adminUserLoginToken');
    if (empty($token)) {
        $token = 'adminUserLoginToken';
    }

    return $token;
}

/**
 * 判断管理员用户是否已登录
 *
 * @return boolean|integer 已登录, 返回用户ID; 否则返回FALSE
 */
function isAdminLogin() {
    $loginToken = getAdminUserLoginToken();
    $userLoginInfo = session($loginToken); // 从SESSION获取用户登录信息
    if ($userLoginInfo && !empty($userLoginInfo['admin_user_id'])) {
        return $userLoginInfo['admin_user_id'];
    }

    return false;
}

/**
 * 获取当前登录的管理员用户信息
 *
 * @return array|null
 */
function getCurrentAdminUserInfo() {
    $loginToken = getAdminUserLoginToken();
    $userLoginInfo = session($loginToken); // 从SESSION获取用户登录信息
    if ($userLoginInfo && !empty($userLoginInfo['admin_user_id'])) {
        return $userLoginInfo;
    }

    return null;
}

/**
 * Redirect page
 *
 * @param string  $url
 * @param integer $code
 * @throws PageNotFound
 */
function redirect($url, $code = 302) {
    // 页面跳转
    if ((strpos($url, '://') || 0 === strpos($url, '/'))) {
        response()->status($code);
        response()->header('Location', $url);
        response()->send();

        exit();
    } else {
        // 代码内跳转
        list($controller, $action) = explode('/', $url, 2);
        $class = '\\SinoPHP\\BbdBoss\\Controller\\' . $controller;
        if (!class_exists($class) || !method_exists($class, $action)) {
            throw new PageNotFound();
        }

        response()->clear();
        request()->setController($controller);
        request()->setAction($action);

        (new $class())->$action();
    }
}

/**
 * Publish a message to MQ
 *
 * @param string  $worker
 * @param array   $params
 * @param boolean $ack
 * @param integer $maxTries
 */
function publish($worker, array $params = [], $ack = true, $maxTries = 1) {
    Queue::setConfig(config('amqp'));
    Queue::connect()->publish($worker, $params, $ack, $maxTries);
}

/**
 * Send a mail
 * (Publish to MQ)
 *
 * @param  string       $subject 邮件主题
 * @param  string|array $address 收件人
 *                               ['张三' => 'example@sinobbd.com', 'example@163.com'],
 *                               'example@sinobbd.com',
 * @param  string       $body    邮件正文
 * @param  boolean      $isHtml  (optional) 正文是否为HTML格式
 * @param  string|array $from    (optional) 发件人
 *                               ['example@sinobbd.com', '张三'],
 *                               'example@sinobbd.com',
 * @return boolean
 */
function sendMail($subject, $address, $body = '', $isHtml = false, $from = null) {
    if (!is_array($address) && !is_string($address)) {
        throw new InvalidArgumentException('Invalid argument: $address');
    }

    $params = [
        'subject' => (string) $subject,
        'address' => $address,
        'body' => (string) $body,
        'isHtml' => (boolean) $isHtml,
    ];

    if ($from && (is_array($from) || is_string($from))) {
        $params['from'] = $from;
    }

    // 发送邮件不需回执
    publish('SendMailCustom', $params, false);

    return true;
}

/**
 *  判断是否为cName
 *
 * @param string $cName
 * @return boolean
 */
function isCName($cName) {
    return preg_match('/^[a-z0-9][a-z0-9-\.]{1,61}[a-z0-9]\.[a-z]{2,}[\.]?$/i', $cName) ? true : false;
}

/**
 * 判断是否为域名
 *
 * @param string $domain
 * @return boolean
 */
function isDomain($domain) {
    return preg_match('/^[a-z0-9][a-z0-9-\.]{1,61}[a-z0-9]\.[a-z]{2,}$/i', $domain) ? true : false;
}